require 'digest/sha1'

class User < ActiveRecord::Base
  belongs_to :role
  belongs_to :address
  
  validates_length_of :username, :within => 3..10
  validates_length_of :password, :within => 3...10
  validates_presence_of :username, :password, :email, :password_confirmation, :salt
  validates_uniqueness_of :username, :email
  validates_confirmation_of :password
  validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i, :message => "Invalid email"

  attr_protected :id, :salt, :roles_id
  attr_accessor :password, :password_confirmation
  
  
  def self.delete(id)
    conn = connection
    i = conn.update("UPDATE users SET deleted = true WHERE id = #{id}")
    return i == 1
  end 


  # ----- Start get methods -----------------
  
  def self.get_by_id(id)
    find(id, :include => [:address], :conditions => ['deleted = ?', false])
    
    rescue ActiveRecord::RecordNotFound
    nil    
  end
  
  
  def self.get_by_username(username)
    find(:first, :include => [:address], :conditions => ['username = ? AND deleted = ?', username, false])
  
    rescue ActiveRecord::RecordNotFound
    nil
  end
  
  
  def self.get_all
    find(:all, :include => [:address], :conditions => ['deleted = ?', false])
  end  
  
  
  
  # ----- Start authentication methods ------
  
  def self.random_string(len)
    #generate a random password consisting of strings and digits
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
    newpass = ""
    1.upto(len) { |i| newpass << chars[rand(chars.size-1)]}   
    return newpass
  end
  
  
  def password=(pass)
    @password = pass
    self.salt = User.random_string(10) if !self.salt?
    self.hashed_password = User.encrypt(@password, self.salt)
  end
  
  
  def self.encrypt(pass, salt)
    Digest::SHA1.hexdigest(pass+salt)
  end
  
  
  def self.authenticate(username, pass)
    u = find(:first, :conditions => ["username = ? AND deleted = ?", username, false])
    return nil if u.nil?
    return u if User.encrypt(pass, u.salt) == u.hashed_password
    nil
  end
  
  def send_new_password
    new_pass = Account.random_string(10)
    self.password = self.password_confirmation = new_pass
    self.save
    Notifications.deliver_forgot_password(self.email, self.login, new_pass)
  end

end
